package com.cloudfun.campusshare.service.impl;

import com.cloudfun.campusshare.common.constant.Code;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.common.model.MerchantAccountDTO;
import com.cloudfun.campusshare.common.model.dto.kjt.KjtAccountRespDTO;
import com.cloudfun.campusshare.common.model.dto.kjt.KjtQueryAccountBalanceListReqDTO;
import com.cloudfun.campusshare.common.model.dto.kjt.KjtQueryAccountBalanceListRespDTO;
import com.cloudfun.campusshare.entity.MerchantAccountEntity;
import com.cloudfun.campusshare.entity.SubMerchantEntity;
import com.cloudfun.campusshare.repo.MerchantAccountRepo;
import com.cloudfun.campusshare.service.KjtService;
import com.cloudfun.campusshare.service.KjtSubMerchantService;
import com.cloudfun.campusshare.service.MerchantAccountService;
import com.cloudfun.campusshare.util.AmountUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * Created by CodeGenerator on 2020/08/14
 */
@Slf4j
@Service
public class MerchantAccountServiceImpl implements MerchantAccountService {

    @Autowired
    private MerchantAccountRepo merchantAccountRepo;

    @Autowired
    private KjtService kjtService;

    @Autowired
    private KjtSubMerchantService subMerchantService;

    @Override
    public void create(MerchantAccountDTO merchantAccountDTO) {
        Optional<MerchantAccountEntity> entityOpt = merchantAccountRepo.findByUserId(merchantAccountDTO.getUserId());
        if (entityOpt.isPresent()) {
            throw new BusinessException(Code.DATA_EXIST, "商户账户已存在");
        }
        MerchantAccountEntity merchantAccountEntity = new MerchantAccountEntity();
        merchantAccountEntity.setSubMerchantId(merchantAccountDTO.getSubMerchantId());
        merchantAccountEntity.setUserId(merchantAccountDTO.getUserId());
        merchantAccountEntity.setAvailableBalance(0);
        merchantAccountEntity.setFrozenBalance(0);
        merchantAccountRepo.save(merchantAccountEntity);
    }

    @Override
    public Optional<MerchantAccountEntity> getEntityByUserId(String userId) {
        return merchantAccountRepo.findByUserId(userId);
    }

    @Override
    public void updateAvailableBalance(String userId, Integer availableBalance) {
        log.info("用户：{}，账户增加可用余额：{}", userId, availableBalance);
        MerchantAccountEntity merchantAccountEntity = merchantAccountRepo.findByUserId(userId).orElseThrow(() -> new BusinessException(Code.NODATA));
        merchantAccountEntity.setAvailableBalance(merchantAccountEntity.getAvailableBalance() + availableBalance);
        merchantAccountRepo.save(merchantAccountEntity);
    }

    @Override
    public void updateFrozenBalance(String userId, Integer frozenBalance) {
        log.info("用户：{}，账户增加冻结余额：{}", userId, frozenBalance);
        MerchantAccountEntity merchantAccountEntity = merchantAccountRepo.findByUserId(userId).orElseThrow(() -> new BusinessException(Code.NODATA));
        merchantAccountEntity.setFrozenBalance(merchantAccountEntity.getFrozenBalance() + frozenBalance);
        merchantAccountRepo.save(merchantAccountEntity);
    }

    @Override
    public List<MerchantAccountEntity> getEntities() {
        return Lists.newArrayList(merchantAccountRepo.findAll());
    }

    @Override
    public void syncAccount() {
        for (MerchantAccountEntity entity : this.getEntities()) {
            String subMerchantId = entity.getSubMerchantId();
            SubMerchantEntity subMerchantEntity = subMerchantService.getEntityById(subMerchantId).orElseThrow(() -> new BusinessException(Code.NODATA));
            KjtQueryAccountBalanceListReqDTO reqDTO = KjtQueryAccountBalanceListReqDTO.builder()
                    .identity(subMerchantEntity.getIdentityId())
                    .build();
            KjtQueryAccountBalanceListRespDTO respDTO = kjtService.queryAccountBalanceList(reqDTO);
            int availableBalance = 0, frozenBalance = 0;
            for (KjtAccountRespDTO accountRespDTO : respDTO.getAccountList()) {
                availableBalance += AmountUtil.strAmount2Int(accountRespDTO.getAvailableBalance());
                frozenBalance += AmountUtil.strAmount2Int(accountRespDTO.getFrozenBalance());
            }
            entity.setAvailableBalance(availableBalance);
            entity.setFrozenBalance(frozenBalance);
            merchantAccountRepo.save(entity);
        }
    }
}